package com.ks.winterwarmimage.wifi;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.MacAddress;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSpecifier;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

import com.ks.winterwarmimage.WinterWarmImageApplication;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

public class WiFiTools {
    /**每隔1分钟扫描一次*/
    public static final long SCAN_INTERVAL_MS = 60000;
    /**命令SSID*/
    public static final String SILENT_DOORBELL_SSID = "Silent_Doorbell";
    private WifiManager wifiManager;
    private Context context;
    private WiFiReceiver wifiReceiver = null;
    private Handler scanHandler = new Handler(Looper.getMainLooper());
    private  Runnable scanRunnable=null;
    /**当前连接的WiFi，在断开时赋值*/
    private WiFi connectWifi;
    /**用来标识WiFi是否处于扫描状态*/
    private boolean isWiFiScan=false;
    /**扫描间隔时长*/
    private long intervalScan=0;
    /**连接管理器*/
    private ConnectivityManager connectivityManager=null;
    /**
     * 扫描结束监听器接口
     */
    public interface WiFiScanListener {
        /**
         * 扫描结束回调
         * @param wifiList 扫描到的WiFi列表
         */
        void onScanFinished(List<WiFi> wifiList);
    }
    public interface WiFiConnectListener {
        /**
         * 连接成功回调
         * @param wifi
         */
        void onConnect(WiFi wifi);
        /**
         * 断开连接回调
         */
        void onDisconnect(WiFi wifi);
    }
    private WiFiScanListener scanListener;
    private WiFiConnectListener connectListener;
    /**
     * 设置扫描监听器
     * @param scanListener 扫描监听器
     */
    public void setScanListener(WiFiScanListener scanListener){
        this.scanListener=scanListener;
    }
    /**
     * 设置连接监听器
     * @param connectListener 连接监听器
     */
    public void setConnectListener(WiFiConnectListener connectListener) {
        this.connectListener = connectListener;
    }
    /** 注销侦听器 */
    public void removeScanListener(){
        this.scanListener=null;
    }
    /** 注销连接监听器 */
    public void removeConnectListener(){
        this.connectListener=null;
    }
    /**
     * 构造函数
     */
    public WiFiTools() {
        this(WinterWarmImageApplication.appContext);
    }
    /**
     * 构造函数
     * @param context 上下文
     */
    public WiFiTools(Context context) {
        this.context = context;
        wifiManager = this.context.getSystemService(WifiManager.class);
    }
    /**
     * 持续扫描
     * @param interval 扫描间隔，单位毫秒，小于等于0表示只扫描一次
     */
    public void startScan(long interval) {
        intervalScan=interval;
        if(scanRunnable==null){
            scanRunnable=new Runnable() {
                @Override
                public void run() {
                    wifiManager.startScan();
                    if(!isWiFiScan)
                        isWiFiScan=true;
                    if(intervalScan>0 ) {
                        scanHandler.postDelayed(this, intervalScan);
                    }
                }
            };
        }
        scanHandler.post(scanRunnable);    //首次执行扫描无需等待，直接执行
    }
    public void stopScan() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            if(scanHandler.hasCallbacks(scanRunnable)) {
                scanHandler.removeCallbacks(scanRunnable);
                scanRunnable=null;
            }
        }else{
            try {
                scanHandler.removeCallbacks(scanRunnable);
                scanRunnable=null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        isWiFiScan=false;
    }

    public boolean isWiFiScan() {
        return isWiFiScan;
    }
    public List<ScanResult> getScanResults() {
        if (!checkSelfPermission()) {
            return null;
        }
        return wifiManager.getScanResults();
    }

    /**
     * 获取扫描的WiFi列表
     * @return 成功返回列表，null 失败
     */
    public List<WiFi> getScanWiFiList() {
        List<ScanResult> scanResults=getScanResults();
        if (scanResults != null && scanResults.size() > 0) {
            List<WiFi> wifiList = new ArrayList<>();
            for (ScanResult result : scanResults) {
                if (result.SSID != null && result.SSID.length() > 0) {
                    WiFi wifi = new WiFi(result.SSID, result.BSSID);
                    wifi.level=result.level;
                    wifi.setCapabilities(result.capabilities);
                    wifiList.add(wifi);
                }
            }
            return wifiList;
        }
        return null;
    }
    /**
     * 注册WiFi广播
     */
    public void regReceiver(){
    // 注册广播接收器
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        wifiReceiver=new WiFiReceiver();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            this.context.registerReceiver(this.wifiReceiver, intentFilter, Context.RECEIVER_EXPORTED);
        }else{
            this.context.registerReceiver(this.wifiReceiver, intentFilter);
        }
    }
    /**
     * 注销广播
     */
    public void unRegReceiver(){
        if(wifiReceiver!=null) {
            this.context.unregisterReceiver(wifiReceiver);
            wifiReceiver=null;
        }
    }

    /**
     * 取消注册网络
     */
    public void unRegisterNetwork() {
        if (connectivityManager != null) {
            connectivityManager.bindProcessToNetwork(null);        //取消绑定的网络
            connectivityManager.unregisterNetworkCallback(networkCallback); //取消注册网络回调
        }
    }
    /**
     * 切换到指定的门铃热点
     * @param bssid 门铃BSSID。从数据库表单中获取
     * @return
     */
    public boolean SwitchToSilentDoorbellAP(String bssid) {
        //需要判断门铃AP释放出在并且SSID匹配
        if (bssid != null) {
            int netId = -1;
            boolean enabledNetwork;
            //String group_bssid = bssid.substring(3);        //裁剪掉前3给字符串，原因是设备端主机的AP模式和STA模式的前2给字符串是不一样的
            //通过已配置列表查找是否存在
            List<WiFi> configuredWifiList = getConfiguredWifiList();   //得到已配置的WiFi信息
            if (configuredWifiList != null && configuredWifiList.size() > 0) {
                for (WiFi configuredWifi : configuredWifiList) {
                    if(configuredWifi.ssid.equals(WiFiTools.SILENT_DOORBELL_SSID)) {
                       // String config_ap_bssid = configuredWifi.bssid.substring(3);
                        //if (config_ap_bssid.equalsIgnoreCase(group_bssid)) {
                        if(configuredWifi.bssidEqualsIgnoreCase(bssid)){
                            netId = configuredWifi.networkId;
                            break;
                        }
                    }
                }
            }
            //通过扫描列表查找是否存在
            List<WiFi> scanWifiList = getWifiScanResults();  //得到扫描的WiFi信息
            if (scanWifiList != null && scanWifiList.size() > 0) {
                for (WiFi scanWifi : scanWifiList) {
                    //判断SSID和BSSID是否匹配
                    if (scanWifi.ssid.equals(WiFiTools.SILENT_DOORBELL_SSID) ) {
                        //String config_ap_bssid = scanWifi.bssid.substring(3); //裁剪掉前3给字符串，原因是设备端主机的AP模式和STA模式的前2给字符串是不一样的
                        //if (config_ap_bssid.equalsIgnoreCase(group_bssid)) {
                        if(scanWifi.bssidEqualsIgnoreCase(bssid)){
                            if (netId != -1) {
                                wifiManager.disconnect(); // 断开当前连接
                                enabledNetwork = wifiManager.enableNetwork(netId, true); // 启用新网络
                                if (enabledNetwork) {
                                    return wifiManager.reconnect(); // 重新连接
                                } else {
                                    return false;
                                }
                            } else {
                                connectWifi(scanWifi.bssid, scanWifi.ssid, "ks666888");
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 网络连接回调
     */
    ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            super.onAvailable(network);
            // connectivityManager.unregisterNetworkCallback(this);
            if (connectivityManager.getBoundNetworkForProcess() != network) {
                connectivityManager.bindProcessToNetwork(network);
                if(connectListener!=null){
                    connectWifi= getConnectedWifi();
                    //oldBssid=connectWifi.bssid;
                    connectListener.onConnect(connectWifi);
                }
                // connectivityManager.bindProcessToNetwork(null);
            }
            //do success processing here...
        }

        @Override
        public void onUnavailable() {
            super.onUnavailable();
            // connectivityManager.unregisterNetworkCallback(this);
            //do failure processing here...
        }
    };
private boolean connectWifi(String bssid, String ssid,String pwd){
       if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.Q){
           NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
                   //.setBssidPattern(new PatternMatcher(new Parcel()))
                   .setSsid(ssid)
                   .setBssid(MacAddress.fromString(bssid))
                   .setWpa2Passphrase(pwd)
                   .build();
           NetworkRequest request =  new NetworkRequest.Builder()
                   .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                   .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)     //能连接到互联网
                   //.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) // 表示网络使用不受限制，可以访问所有网络服务
                   .setNetworkSpecifier(specifier)
                   .build();
           if(connectivityManager==null) {
               connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
           }
           connectivityManager.requestNetwork(request, networkCallback);
           return true;
       }else{
           WifiConfiguration wifiConfig = new WifiConfiguration();
           // 使用双引号来包裹 SSID 字符串，这样即使 SSID 包含特殊字符也能正确识别
           wifiConfig.SSID = String.format("\"%s\"",ssid);
           wifiConfig.preSharedKey = String.format("\"%s\"", pwd);
           wifiConfig.BSSID = String.format("\"%s\"", bssid);
           int netId = wifiManager.addNetwork(wifiConfig);
           // 连接到指定的 Wi-Fi 网络
           if (netId != -1) {
               wifiManager.disconnect(); // 断开当前连接
               boolean enabledNetwork = wifiManager.enableNetwork(netId, true); // 启用新网络
               if (enabledNetwork) {
                   return wifiManager.reconnect(); // 重新连接
               }
           } else {
               return false;
           }
       }
       return false;
}
    /**
     * 切换到APP开始时存储的网络，如果不在范围，切换到一个已配置网络
     */
    public boolean switchToOldWiFi(String bssid) {
        boolean enabledNetwork;
        //WiFi currentWiFi = getConnectedWifi();              //得到当前热点
        List<WiFi> scanWifiList = getWifiScanResults();  //得到扫描的WiFi信息
        if (scanWifiList != null && scanWifiList.size() > 0) {
            if (WinterWarmImageApplication.lastWifi != null && !WinterWarmImageApplication.lastWifi.ssid.equals(WiFiTools.SILENT_DOORBELL_SSID)) {
                for (WiFi scanWifi : scanWifiList) {
                    if (scanWifi.bssid.equalsIgnoreCase(WinterWarmImageApplication.lastWifi.bssid)) {
                        wifiManager.disconnect(); // 断开当前连接
                        enabledNetwork = wifiManager.enableNetwork(WinterWarmImageApplication.lastWifi.networkId, true);
                        if (enabledNetwork) {
                            wifiManager.reconnect();        //重新连接到网络
                            return true;
                        } else {
                            break;
                        }
                    }
                }
            }
            List<WiFi> configuredWifiList = getConfiguredWifiList();   //得到已配置的WiFi信息
            if (configuredWifiList != null) {
                for (WiFi scanWifi : scanWifiList) {
                    for (WiFi configuredWifi : configuredWifiList) {
                        if(connectWifi!=null) {
                            //扫描到的WiFi和已配置的WiFi相同，并且不是当前连接的WiFi
                            if (scanWifi.bssid.equalsIgnoreCase(configuredWifi.bssid) &&
                                    !scanWifi.bssid.equalsIgnoreCase(connectWifi.bssid)) {
                                wifiManager.disconnect(); // 断开当前连接
                                enabledNetwork = wifiManager.enableNetwork(configuredWifi.networkId, true);
                                if (enabledNetwork) {
                                    wifiManager.reconnect();        //重新连接到网络
                                    return true;
                                } else {
                                    return false;
                                }
                            }
                        }else{
                            if(scanWifi.bssid.equalsIgnoreCase(configuredWifi.bssid)){
                                enabledNetwork = wifiManager.enableNetwork(configuredWifi.networkId, true);
                                if (enabledNetwork) {
                                    wifiManager.reconnect();        //重新连接到网络
                                    return true;
                                } else {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }else{
                //connectWifi= getConnectedWifi();
//                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
//                    WifiNetworkSuggestion suggestion = new WifiNetworkSuggestion.Builder()
//                            .setSsid(WiFiTools.SILENT_DOORBELL_SSID)
//                            .setWpa2Passphrase("ks666888")
//                            .setBssid(MacAddress.fromString(bssid))
//                            .build();
//                    List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
//                    suggestions.add(suggestion);
//                    ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
//                    connectivityManager.getActiveNetwork().describeContents();
//                }
//                ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
//                connectivityManager.bindProcessToNetwork(null);
//               boolean connected =  wifiManager.disconnect(); // 断开当前连接
//                connected=wifiManager.disableNetwork(connectWifi.networkId);
//                connected= wifiManager.removeNetwork(connectWifi.networkId);
            }
        }
        //断开当前连接的网络（可以不理睬）
        //wifiManager.disconnect();
        return false;
    }

    /**
     * 获取当前连接的WiFi SSID
     * @return
     */
    public WiFi getConnectedWifi() {
        WifiInfo wifiInfo= wifiManager.getConnectionInfo();
        if(wifiInfo!=null){
            String ssid = wifiInfo.getSSID();
            String mac = wifiInfo.getBSSID();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                wifiInfo.getCurrentSecurityType();
            }
            // 去除双引号
            if (ssid != null && ssid.startsWith("\"") && ssid.endsWith("\"")) {
                ssid = ssid.substring(1, ssid.length() - 1);
            }
            if (mac != null && mac.startsWith("\"") && mac.endsWith("\"")) {
                mac = mac.substring(1, mac.length() - 1);
            }
            return new WiFi(ssid,mac,wifiInfo.getNetworkId());
        }
        return null;
    }

    /**
     * 获取可用WiFi列表（不通过广播接收器直接获取）
     * @return
     */
    public List<WiFi> getWifiScanResults() {
        List<WiFi> wifiList=null;
        if (wifiManager.isWifiEnabled()) {
            if (!checkSelfPermission()) {
                return null;
            }
            pauseBroadcast(true);     //暂停广播
            wifiManager.startScan();
            List<ScanResult> scanResults = wifiManager.getScanResults();
            if (scanResults != null && scanResults.size() > 0) {
                wifiList = new ArrayList<>();
                for (ScanResult result : scanResults) {
                    if (result.SSID != null && result.SSID.length() > 0) {
                       WiFi wifi = new WiFi(result.SSID, result.BSSID);
                        wifi.setCapabilities(result.capabilities);
                        wifiList.add(wifi);
                    }
                }
            }
            pauseBroadcast(false); //恢复广播
        }
        return wifiList;
    }

    /**
     * 获取已配置的网络列表
     * @return
     */
    public List<WiFi> getConfiguredWifiList() {
            if (wifiManager.isWifiEnabled()) {
                if (!checkSelfPermission()) {
                    return null;
                }
                List<WifiConfiguration> wifiConfigurations = wifiManager.getConfiguredNetworks();
                if (wifiConfigurations != null && wifiConfigurations.size() > 0) {
                    List<WiFi> wifiList = new ArrayList<>();
                    for (WifiConfiguration configuration : wifiConfigurations) {
                        if (configuration.SSID != null && configuration.SSID.length() > 0) {
                            wifiList.add(new WiFi(configuration.SSID, configuration.BSSID, configuration.networkId));
                        }
                    }
                    return wifiList;
                }
            }
        return null;
    }
    /**
     * 检查权限
     * @return
     */
    private boolean checkSelfPermission(){
        return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * 暂停扫描广播
     * @param pause 暂停
     */
    private void pauseBroadcast(boolean pause){
//    PackageManager packageManager = context.getPackageManager();
//    ComponentName componentName = new ComponentName(context, WiFiTools.WiFiReceiver.class);
//    // 禁用/启用广播接收器
//    packageManager.setComponentEnabledSetting(componentName,
//            (pause?PackageManager.COMPONENT_ENABLED_STATE_DISABLED:PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
//            PackageManager.DONT_KILL_APP);
        if (pause) {
            //((WiFiTools) context).unregisterReceiver();
            regReceiver();
        } else {
           // ((WiFiTools) context).registerReceiver();
            unRegReceiver();
        }
}
    /**
     * 扫描广播侦听器
     */
    private   class WiFiReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action= intent.getAction();
            if(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action)) {
                if(isWiFiScan) {
                    if (scanListener != null) {
                        List<WiFi> wifiList = getScanWiFiList();
                        scanListener.onScanFinished(wifiList);
                    }
                    if(intervalScan<=0) {
                        stopScan();
                    }
                }
            }else if(ConnectivityManager.CONNECTIVITY_ACTION.equals(action)){
                if(connectListener!=null){
                    ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                    NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
                    if(networkInfo!=null && networkInfo.getType()==ConnectivityManager.TYPE_WIFI){
                        if(networkInfo.isConnected()){
                           WiFi wiFi= getConnectedWifi();
                            if(connectWifi!=null && !connectWifi.bssid.equals(wiFi.bssid)) {   //两个BSSID不相同，说明已经切换到别的wifi
                                if (connectivityManager != null) {
                                    connectivityManager.bindProcessToNetwork(null);        //取消绑定的网络
                                    connectivityManager.unregisterNetworkCallback(networkCallback);
                                }
                            }
                            connectWifi=wiFi;
                            connectListener.onConnect(connectWifi);
                        }else{
                            connectListener.onDisconnect(connectWifi);
                            connectWifi=null;
                        }
                    }
                }
            }
        }
    }
    public static class WiFi{
        @IntDef({ Capabilities.UNENCRYPTED, Capabilities.WEP, Capabilities.WPA_PSK, Capabilities.WPA2_PSK, Capabilities.WPA3_PSK})
        @Retention(RetentionPolicy.SOURCE)
        public @interface Capabilities{
            /**开放网络*/
            int UNENCRYPTED=0;
            /**WEP加密*/
            int WEP=1;
            /**WPA加密*/
            int WPA_PSK=2;
             /**WPA2加密*/
             int WPA2_PSK=3;
            /**WPA3加密*/
            int WPA3_PSK=4;
        }
        /**
         * AP端WiFi名称
         */
        public String ssid;
        /**
         * AP端WiFi mac地址
         */
        public String bssid;
        /**
         * WiFi配置网络ID
         */
        public int networkId;
        /**加密方式*/
        public @Capabilities int capabilities= Capabilities.UNENCRYPTED;
        /**信号强度*/
        public int level;
        /**
         * 构造方法
         * @param ssid WiFi名称
         * @param bssid WiFi mac地址
         */
        public WiFi(String ssid,String bssid){
            this(ssid,bssid,-1);
        }
        /**
         * 构造方法
         * @param ssid AP端 WiFi名称
         * @param bssid AP端WiFi mac地址
         * @param networkId WiFi配置网络ID
         */
        public WiFi(String ssid,String bssid,int networkId){
            this.ssid=ssid;
            this.bssid=bssid;
            this.networkId=networkId;
        }

        /**
         * 比较两个bssid 是否相等（默认将两个都是null及长度小于17的bssid处理为不相等）
         * @param bssid 要比较的bssid
         * @return
         */
        public boolean bssidEqualsIgnoreCase(String bssid){
            return bssidEqualsIgnoreCase(bssid,this.bssid);
        }

        /**
         * 比较两个bssid 是否相等（默认将两个都是null及长度小于17的bssid处理为不相等）
         * @param bssid1 需要比较的bssid1
         * @param bssid2 需要比较的bssid2
         * @return
         */
        public static boolean bssidEqualsIgnoreCase(String bssid1,String bssid2){
            if(bssid1!=null && bssid1.length()==17 && bssid2!=null && bssid2.length()==17){
                if(bssid1.equalsIgnoreCase(bssid2)) {   //完全相等（不区分大小写）
                    return true;
                }else{
                    //去掉左边三个字符串后进行比较
                    String leftBssid_1=bssid1.substring(3);
                    String leftBssid_2=bssid2.substring(3);
                    if(leftBssid_1.equalsIgnoreCase(leftBssid_2)){
                        return true;
                    }else{
                        //去掉右边三个字符串后进行比较
                        String rightBssid_1=bssid1.substring(0,bssid1.length()-3);
                        String rightBssid_2=bssid2.substring(0,bssid2.length()-3);
                        if(rightBssid_1.equalsIgnoreCase(rightBssid_2)){
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        /**
         * 设置加密方式
         * @param capabilities 加密方式字符串
         */
        public void setCapabilities(String capabilities){
            if(capabilities!=null && capabilities.length()>2){
                if(capabilities.contains("WPA3")){
                    this.capabilities= Capabilities.WPA3_PSK;
                }else if(capabilities.contains("WPA2")){
                    this.capabilities= Capabilities.WPA2_PSK;
                }else if(capabilities.contains("WPA")){
                    this.capabilities= Capabilities.WPA_PSK;
                }else if(capabilities.contains("WEP")){
                    this.capabilities= Capabilities.WEP;
                }else{
                    this.capabilities= Capabilities.UNENCRYPTED;
                }
            }else{
                this.capabilities= Capabilities.UNENCRYPTED;
            }
        }
        public String getLevelName() {
            return null;
        }
    }
}
